package Java进阶.JDK8新特性;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import Java基础.模拟ArrayList.Cat;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;

/**
 * @function funciton的深入理解
 * @author 肖荣辉
 * @date 2022年9月1日
*/
public class FunctionStudy {
	
	public static void main(String[] args) {
		
//		Cat cat = new Cat();
//		 
//		cat.setAge(11);
//		
//		Object obj = testApply(Cat::getAge , cat);
//		
//		System.out.println(obj.toString());
//		
//		//传入参数"1", fun2在参数"1"后面拼接个0,然后用fun1强转为整形返回,得到的是10
//		Integer a = testCompose(str->Integer.parseInt(str)  , str-> str + "0" , "1");
//		
//		System.out.println(a);
		
//		//传入参数2,执行fun1,转成int后作为入参传给fun2,然后+0.5得到一个double类型
//		double b = testAndThen(str->Integer.parseInt(str) , x->2 + 0.5 , "2");
//	
//		System.out.println(b);
		
	}
	
	/**
	 * @function 测试identity方法 , 就是生成一个function,总是返回传入的参数 , 以单表item->item
	 * @author 肖荣辉
	 * @date 2022年9月1日
	*/
	public static  void  testIdentity() {
		
		Cat cat = new Cat("小花" , 1);
		
		List<Cat> list = CollUtil.newArrayList(cat);
		
		//Map<Integer, Cat> map = 	CollStreamUtil.toMap(list , Cat::getAge ,  item->item);
		
		//使用Function.identity()代替上述写法
		Map<Integer, Cat> map = 	CollStreamUtil.toMap(list , Cat::getAge ,  Function.identity());
	
		System.out.println(map);
	}
	/**
	 * @function 测试andThen方法
	 * @author 肖荣辉
	 * @date 2022年9月1日
	 */
	public static  <T , R , V> V testAndThen(Function<T, R> fun1 , Function<R , V> fun2 , T t ) {
		
		//执行完fun1 , 然后再执行fun2, fun1的返回值作为fun2的入参
		//先执行fun1,然后返回值给fun2作为入参, 最后返回V
		return fun1.andThen(fun2).apply(t);
		
	}
	
	/**
	 * @function 测试compose方法
	 * @author 肖荣辉
	 * @date 2022年9月1日
	 */
	public static  <T , R> R testCompose(Function<T, R> fun1 , Function<T, T> fun2 , T t ) {
		
		//组合fun1和fun2, fun2的输出要和fun1的入参保持一致 
		//先执行fun2,然后返回值给fun1作为入参, 最后返回R
		return fun1.compose(fun2).apply(t);
	}
	
	
	/**
	 * @function 测试apply方法
	 * @param fun 传入的function
	 * @param t 参数  (泛型T是参数 , R是返回值)
	 * @author 肖荣辉
	 * @date 2022年9月1日
	*/
	public static <T , R> R testApply(Function<T, R> fun , T t){
		return fun.apply(t);
	}
	
}
